home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / daemons / lprm_fix.z / lprm_fix / lpr / common_source / rmjob.c~ < prev    next >
Encoding:
Text File  |  1993-05-04  |  8.1 KB  |  326 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)rmjob.c    5.7 (Berkeley) 6/1/90";
  36. #endif /* not lint */
  37.  
  38. /*
  39.  * rmjob - remove the specified jobs from the queue.
  40.  */
  41.  
  42. #include "lp.h"
  43. #include "pathnames.h"
  44.  
  45. /*
  46.  * Stuff for handling lprm specifications
  47.  */
  48. extern char    *user[];        /* users to process */
  49. extern int    users;            /* # of users in user array */
  50. extern int    requ[];            /* job number of spool entries */
  51. extern int    requests;        /* # of spool requests */
  52. extern char    *person;        /* name of person doing lprm */
  53.  
  54. char    root[] = "root";
  55. int    all = 0;        /* eliminate all files (root only) */
  56. int    cur_daemon;        /* daemon's pid */
  57. char    current[40];        /* active control file name */
  58.  
  59. int    iscf();
  60.  
  61. rmjob()
  62. {
  63.     register int i, nitems;
  64.     int assasinated = 0;
  65.     struct direct **files;
  66.     char *cp;
  67.  
  68.     if ((i = pgetent(line, printer)) < 0)
  69.         fatal("cannot open printer description file");
  70.     else if (i == 0)
  71.         fatal("unknown printer");
  72.     if ((SD = pgetstr("sd", &bp)) == NULL)
  73.         SD = _PATH_DEFSPOOL;
  74.     if ((LO = pgetstr("lo", &bp)) == NULL)
  75.         LO = DEFLOCK;
  76.     if ((LP = pgetstr("lp", &bp)) == NULL)
  77.         LP = _PATH_DEFDEVLP;
  78.     if ((RP = pgetstr("rp", &bp)) == NULL)
  79.         RP = DEFLP;
  80.     RM = pgetstr("rm", &bp);
  81.     if (cp = checkremote())
  82.         printf("Warning: %s\n", cp);
  83.  
  84.     /*
  85.      * If the format was `lprm -' and the user isn't the super-user,
  86.      *  then fake things to look like he said `lprm user'.
  87.      */
  88.     if (users < 0) {
  89.         if (getuid() == 0)
  90.             all = 1;    /* all files in local queue */
  91.         else {
  92.             user[0] = person;
  93.             users = 1;
  94.         }
  95.     }
  96.     if (!strcmp(person, "-all")) {
  97.         if (from == host)
  98.             fatal("The login name \"-all\" is reserved");
  99.         all = 1;    /* all those from 'from' */
  100.         person = root;
  101.     }
  102.  
  103.     if (chdir(SD) < 0)
  104.         fatal("cannot chdir to spool directory");
  105. #if    0
  106.     if ((nitems = scandir(".", &files, iscf, NULL)) < 0)
  107. #else
  108.     if ((nitems = scandir(".", &files, &iscf, alphasort)) < 0)
  109. #endif      
  110.         fatal("cannot access spool directory");
  111.  
  112.     if (nitems) {
  113.         /*
  114.          * Check for an active printer daemon (in which case we
  115.          *  kill it if it is reading our file) then remove stuff
  116.          *  (after which we have to restart the daemon).
  117.          */
  118.         if (lockchk(LO) && chk(current)) {
  119.             assasinated = kill(cur_daemon, SIGINT) == 0;
  120.             if (!assasinated)
  121.                 fatal("cannot kill printer daemon");
  122.         }
  123.         /*
  124.          * process the files
  125.          */
  126.         for (i = 0; i < nitems; i++)
  127.             process(files[i]->d_name);
  128.     }
  129.     rmremote();
  130.     /*
  131.      * Restart the printer daemon if it was killed
  132.      */
  133.     if (assasinated && !startdaemon(printer))
  134.         fatal("cannot restart printer daemon\n");
  135.     exit(0);
  136. }
  137.  
  138. /*
  139.  * Process a lock file: collect the pid of the active
  140.  *  daemon and the file name of the active spool entry.
  141.  * Return boolean indicating existence of a lock file.
  142.  */
  143. lockchk(s)
  144.     char *s;
  145. {
  146.     register FILE *fp;
  147.     register int i, n;
  148.  
  149.     if ((fp = fopen(s, "r")) == NULL)
  150.         if (errno == EACCES)
  151.             fatal("can't access lock file");
  152.         else
  153.             return(0);
  154.     if (!getline(fp)) {
  155.         (void) fclose(fp);
  156.         return(0);        /* no daemon present */
  157.     }
  158.     cur_daemon = atoi(line);
  159.     if (kill(cur_daemon, 0) < 0) {
  160.         (void) fclose(fp);
  161.         return(0);        /* no daemon present */
  162.     }
  163.     for (i = 1; (n = fread(current, sizeof(char), sizeof(current), fp)) <= 0; i++) {
  164.         if (i > 5) {
  165.             n = 1;
  166.             break;
  167.         }
  168.         sleep(i);
  169.     }
  170.     current[n-1] = '\0';
  171.     (void) fclose(fp);
  172.     return(1);
  173. }
  174.  
  175. /*
  176.  * Process a control file.
  177.  */
  178. process(file)
  179.     char *file;
  180. {
  181.     FILE *cfp;
  182.  
  183.     if (!chk(file))
  184.         return;
  185.     if ((cfp = fopen(file, "r")) == NULL)
  186.         fatal("cannot open %s", file);
  187.     while (getline(cfp)) {
  188.         switch (line[0]) {
  189.         case 'U':  /* unlink associated files */
  190.             if (from != host)
  191.                 printf("%s: ", host);
  192.             printf(unlink(line+1) ? "cannot dequeue %s\n" :
  193.                 "%s dequeued\n", line+1);
  194.         }
  195.     }
  196.     (void) fclose(cfp);
  197.     if (from != host)
  198.         printf("%s: ", host);
  199.     printf(unlink(file) ? "cannot dequeue %s\n" : "%s dequeued\n", file);
  200. }
  201.  
  202. /*
  203.  * Do the dirty work in checking
  204.  */
  205. chk(file)
  206.     char *file;
  207. {
  208.     register int *r, n;
  209.     register char **u, *cp;
  210.     FILE *cfp;
  211.  
  212.     /*
  213.      * Check for valid cf file name (mostly checking current).
  214.      */
  215.     if (strlen(file) < 7 || file[0] != 'c' || file[1] != 'f')
  216.         return(0);
  217.  
  218.     if (all && (from == host || !strcmp(from, file+6)))
  219.         return(1);
  220.  
  221.     /*
  222.      * get the owner's name from the control file.
  223.      */
  224.     if ((cfp = fopen(file, "r")) == NULL)
  225.         return(0);
  226.     while (getline(cfp)) {
  227.         if (line[0] == 'P')
  228.             break;
  229.     }
  230.     (void) fclose(cfp);
  231.     if (line[0] != 'P')
  232.         return(0);
  233.  
  234.     if (users == 0 && requests == 0)
  235.         return(!strcmp(file, current) && isowner(line+1, file));
  236.     /*
  237.      * Check the request list
  238.      */
  239.     for (n = 0, cp = file+3; isdigit(*cp); )
  240.         n = n * 10 + (*cp++ - '0');
  241.     for (r = requ; r < &requ[requests]; r++)
  242.         if (*r == n && isowner(line+1, file))
  243.             return(1);
  244.     /*
  245.      * Check to see if it's in the user list
  246.      */
  247.     for (u = user; u < &user[users]; u++)
  248.         if (!strcmp(*u, line+1) && isowner(line+1, file))
  249.             return(1);
  250.     return(0);
  251. }
  252.  
  253. /*
  254.  * If root is removing a file on the local machine, allow it.
  255.  * If root is removing a file from a remote machine, only allow
  256.  * files sent from the remote machine to be removed.
  257.  * Normal users can only remove the file from where it was sent.
  258.  */
  259. isowner(owner, file)
  260.     char *owner, *file;
  261. {
  262.     if (!strcmp(person, root) && (from == host || !strcmp(from, file+6)))
  263.         return(1);
  264.     if (!strcmp(person, owner) && !strcmp(from, file+6))
  265.         return(1);
  266.     if (from != host)
  267.         printf("%s: ", host);
  268.     printf("%s: Permission denied\n", file);
  269.     return(0);
  270. }
  271.  
  272. /*
  273.  * Check to see if we are sending files to a remote machine. If we are,
  274.  * then try removing files on the remote machine.
  275.  */
  276. rmremote()
  277. {
  278.     register char *cp;
  279.     register int i, rem;
  280.     char buf[BUFSIZ];
  281.  
  282.     if (!sendtorem)
  283.         return;    /* not sending to a remote machine */
  284.  
  285.     /*
  286.      * Flush stdout so the user can see what has been deleted
  287.      * while we wait (possibly) for the connection.
  288.      */
  289.     fflush(stdout);
  290.  
  291.     sprintf(buf, "\5%s %s", RP, all ? "-all" : person);
  292.     cp = buf;
  293.     for (i = 0; i < users; i++) {
  294.         cp += strlen(cp);
  295.         *cp++ = ' ';
  296.         strcpy(cp, user[i]);
  297.     }
  298.     for (i = 0; i < requests; i++) {
  299.         cp += strlen(cp);
  300.         (void) sprintf(cp, " %d", requ[i]);
  301.     }
  302.     strcat(cp, "\n");
  303.     rem = getport(RM);
  304.     if (rem < 0) {
  305.         if (from != host)
  306.             printf("%s: ", host);
  307.         printf("connection to %s is down\n", RM);
  308.     } else {
  309.         i = strlen(buf);
  310.         if (write(rem, buf, i) != i)
  311.             fatal("Lost connection");
  312.         while ((i = read(rem, buf, sizeof(buf))) > 0)
  313.             (void) fwrite(buf, 1, i, stdout);
  314.         (void) close(rem);
  315.     }
  316. }
  317.  
  318. /*
  319.  * Return 1 if the filename begins with 'cf'
  320.  */
  321. iscf(d)
  322.     struct direct *d;
  323. {
  324.     return(d->d_name[0] == 'c' && d->d_name[1] == 'f');
  325. }
  326.